package com.newhis.filter;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.newhis.constant.TokenConstant;
import com.newhis.servlet.RequestWrapper;
import com.newhis.utils.PatternUtils;
import com.newhis.vo.ResultVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

@Component
public class RequestDecryptionFilter implements Filter {
    private static final Logger log = LoggerFactory.getLogger(RequestDecryptionFilter.class);
    @Value("${sm4.encrypt}")
    private boolean encrypt = false;
    @Value("${sm4.ignoreUrl}")
    private List<String> ignoreUrl = new ArrayList<>();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpRequest =(HttpServletRequest)servletRequest;
        HttpServletResponse httpResponse =(HttpServletResponse)servletResponse;
        String uri = httpRequest.getRequestURI();
        String [] uris = new String[ignoreUrl.size()];
        boolean flag = PatternUtils.matchList(ObjectUtil.isNotEmpty(ignoreUrl) ? ignoreUrl.toArray(uris) : null, uri);
        if(flag || !encrypt) {
            try {
                filterChain.doFilter(httpRequest, httpResponse);
            } catch (IOException | ServletException e) {
                e.printStackTrace();
            }
        }else{
            try{
                //获取token
                String token = getToken(httpRequest);
                RequestWrapper requestWrapper = new RequestWrapper(httpRequest,token,encrypt);
                filterChain.doFilter(requestWrapper,servletResponse);
            }catch(Exception e){
                try {
                    getFailResponse(httpResponse, "数据解密异常");
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }
                log.error("请求数据解密异常，", e);
            }
        }
    }

    @Override
    public void destroy() {

    }

    private void getFailResponse(HttpServletResponse response, String msg) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = null;
        out = response.getWriter();
        //加密后的错误消息
        out.write(JSONObject.toJSONString(ResultVo.error(msg)));
        out.flush();
        out.close();
    }

    /**
     * 获取请求token
     */
    private String getToken(HttpServletRequest request) {
        String token = request.getHeader(TokenConstant.HEADER);
        if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstant.TOKEN_PREFIX)) {
            token = token.replace(TokenConstant.TOKEN_PREFIX, "");
        }
        return token;
    }

}
